package vns.client.presenter;

import java.util.ArrayList;
import java.util.List;

import vns.client.VNSmartUI;
import vns.client.helper.RPCCall;
import vns.client.service.ObjectPropertyTypeService;
import vns.client.service.ObjectPropertyTypeServiceAsync;
import vns.client.service.ObjectServiceAsync;
import vns.client.service.ObjectTypeService;
import vns.client.service.ObjectTypeServiceAsync;
import vns.client.view.ObjectDetailUI;
import vns.shared.ObjectDTO;
import vns.shared.ObjectPropertyDTO;
import vns.shared.ObjectTypeDTO;
import vns.shared.ObjectValueDTO;

import com.google.appengine.api.datastore.KeyFactory;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;

public class ObjectDetailPresenter implements Presenter {

	@Override
	public void go(HasWidgets container) {
		// Window.alert(display.getCurrentObjectTypeDTO().getName() + "|"
		// + display.getListObjectPropertyDTO().size());
		container.clear();
		container.add(display.asWidget());
		doInitTable();
	}

	public interface Display {
		Button getUpdateButton();
		Button getCancelButton();

		ObjectDTO getCurrentObjectDTO();

		void setCurrentObjectDTO(ObjectDTO o);

		ObjectTypeDTO getCurrentObjectTypeDTO();

		void setCurrentObjectTypeDTO(ObjectTypeDTO ot);

		List<ObjectPropertyDTO> getListObjectPropertyDTO();

		void setListObjectPropertyDTO(List<ObjectPropertyDTO> listopt);

		String getCurrentOperation();

		void setCurrentOperation(String operation);

		Widget asWidget();

		void render();

		boolean checkRequired();
	}

	private final Display display;
	private final SimpleEventBus eventBus;
	private final ObjectServiceAsync rpcObject;
	private final ObjectPropertyTypeServiceAsync rpcServicePtype = GWT
			.create(ObjectPropertyTypeService.class);
	private final ObjectTypeServiceAsync rpcOType = GWT
			.create(ObjectTypeService.class);

	public ObjectDetailPresenter(ObjectDetailUI view, SimpleEventBus eventBus,
			ObjectDTO o, ObjectTypeDTO ot, List<ObjectPropertyDTO> list,
			ObjectServiceAsync rpcObject, String operation) {
		this.display = view;
		this.eventBus = eventBus;
		if (o == null) {
			// Window.alert("Khoi tao ObjectDTO voi type = " + ot.getName()
			// + " listsize = " + list.size());
			o = new ObjectDTO();
			for (ObjectPropertyDTO pDTO : list) {
				pDTO.setListObjectValue(new ArrayList<ObjectValueDTO>());
			}
			o.setListProperty(list);
			o.setOtype(KeyFactory.keyToString(ot.getId()));
			o.setType(ot.getName());
		}
		display.setCurrentObjectDTO(o);
		display.setCurrentObjectTypeDTO(ot);
		display.setListObjectPropertyDTO(list);
		this.rpcObject = rpcObject;
		display.setCurrentOperation(operation);

		bind();
	}

	private boolean bind() {
		display.getUpdateButton().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				doUpdate();
			}
		});
		display.getCancelButton().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				VNSmartUI.get().callLastToken();
			}
		});
		return false;
	}

	/***************************************************************************/

	private void doInitTable() {
		display.render();
	}

	private void doUpdate() {
		if (display.checkRequired()) {
			new RPCCall<ObjectDTO>() {

				@Override
				public void onFailure(Throwable caught) {
					Window.alert("Có lỗi khi đang cập nhật!");
				}

				@Override
				public void onSuccess(ObjectDTO result) {
					Window.alert("Cập nhật thành công!");
					VNSmartUI.get().callLastToken();
				}

				@Override
				protected void callService(AsyncCallback<ObjectDTO> cb) {
					rpcObject.Update(display.getCurrentObjectDTO(), cb);
				}
			}.retry(3);
		}
	}
}
